#include "QOgreWidgetDemo.h"
#include "OGRE/RenderSystems/GL/OgreGLPlugin.h"
#include "Ogre3D/QOgreWidget.h"

#include "Comm/console.h"
#include "Comm/settingsdialog.h"

#include "ui_phone_fly.h"

#include <QGroupBox>
#include <QPushButton>
#include <QVBoxLayout>
#include <QMessageBox>
#include <QtSerialPort/QSerialPort>


QOgreWidgetDemo::QOgreWidgetDemo()  
{
	ui = new Ui::MainWindow;
	ui->setupUi(this);
	
    console = new Console;
    console->setEnabled(true);
//! [1]
    serial = new QSerialPort(this);
//! [1]
    settings = new SettingsDialog;
	
	
	
    connect(serial, SIGNAL(error(QSerialPort::SerialPortError)), this,
            SLOT(handleError(QSerialPort::SerialPortError)));

//! [2]
    connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
//! [2]
    connect(console, SIGNAL(getData(QByteArray)), this, SLOT(writeData(QByteArray)));
	
	connect(ui->actionController, SIGNAL(toggled(bool)), this, SLOT(setController(bool)));
	
    initActionsConnections();
	
	
	createQtWidgets();
    mOgreWidget->createScene();
	
    mOgreWidget->renderOneFrame();
	this->show();
	
}


QOgreWidgetDemo::~QOgreWidgetDemo() {
    delete mOgreWidget;
}



    
void QOgreWidgetDemo::createQtWidgets() {
    QGroupBox *mainGroup = new QGroupBox;
    QVBoxLayout *mainLayout = new QVBoxLayout;
    QVBoxLayout *mainLayout2 = new QVBoxLayout;
    mOgreWidget = new QOgreWidget(this, mainGroup);
    
	/*
	QPushButton *buttonZoomIn = new QPushButton(tr("Zoom &In"));
    QPushButton *buttonZoomOut = new QPushButton(tr("Zoom &Out"));
    mainLayout->addWidget(buttonZoomIn);
    mainLayout->addWidget(buttonZoomOut);
    connect(buttonZoomIn, SIGNAL(released()), this, SLOT(onZoomIn()));
    connect(buttonZoomOut, SIGNAL(released()), this, SLOT(onZoomOut()));
    */
    mainLayout->addWidget(mOgreWidget);
    mainGroup->setLayout(mainLayout);
    setCentralWidget(mainGroup);

}



void QOgreWidgetDemo::ogreMousePressEvent(QMouseEvent *event) {
    mOgreWidget->getCameraMan()->injectMouseDown(*event);

}


void QOgreWidgetDemo::ogreMouseMoveEvent(QMouseEvent *event) {
    if (event->buttons() & Qt::LeftButton) {
        std::cout << "mouse Moved (left button pressed)";
    } else if (event->buttons() & Qt::RightButton) {
        std::cout << "mouse Moved (right button pressed)";
    }
    int x = event->x();
    int y = event->y();
    int dx = mMouseMoveXOld - x;
    int dy = mMouseMoveYOld - y;
    
    mMouseMoveXOld = x;
    mMouseMoveYOld = y;
    
    mOgreWidget->getCameraMan()->injectMouseMove(*event);
}

void QOgreWidgetDemo::ogreKeyPressEvent(QKeyEvent *event){
	float force = 50;
	switch(event->key() ){
	case Qt::Key_8:
		mOgreWidget->setFingerFactor(1);
		mOgreWidget->applyForceToAirplane(-force,0.0,0.0);
		mOgreWidget->setFingerFactor(0);
		break;
	case Qt::Key_2:
		mOgreWidget->setFingerFactor(1);
		mOgreWidget->applyForceToAirplane(force,0.0,0.0);
		mOgreWidget->setFingerFactor(0);
		break;
	case Qt::Key_6:
		mOgreWidget->setFingerFactor(1);
		mOgreWidget->applyForceToAirplane(0.0,0.0,force);
		mOgreWidget->setFingerFactor(0);
		break;
	case Qt::Key_4:
		mOgreWidget->setFingerFactor(1);
		mOgreWidget->applyForceToAirplane(0.0,0.0,-force);
		mOgreWidget->setFingerFactor(0);
		break;
	case Qt::Key_5:
		mOgreWidget->setFingerFactor(1);
		mOgreWidget->applyForceToAirplane(0.0,force,0.0);
		mOgreWidget->setFingerFactor(0);
		break;
	}
    mOgreWidget->getCameraMan()->injectKeyDown(*event);
}
void QOgreWidgetDemo::ogreKeyReleaseEvent(QKeyEvent *event){
	
    mOgreWidget->getCameraMan()->injectKeyUp(*event);

}




void QOgreWidgetDemo::openSerialPort()
{
    SettingsDialog::Settings p = settings->settings();
    serial->setPortName(p.name);
    serial->setBaudRate(p.baudRate);
    serial->setDataBits(p.dataBits);
    serial->setParity(p.parity);
    serial->setStopBits(p.stopBits);
    serial->setFlowControl(p.flowControl);
    if (serial->open(QIODevice::ReadWrite)) {
            console->setEnabled(true);
            console->setLocalEchoEnabled(p.localEchoEnabled);
            ui->actionConnect->setEnabled(false);
            ui->actionDisconnect->setEnabled(true);
            ui->actionConfigure->setEnabled(false);
            ui->statusBar->showMessage(tr("Connected to %1 : %2, %3, %4, %5, %6")
                                       .arg(p.name).arg(p.stringBaudRate).arg(p.stringDataBits)
                                       .arg(p.stringParity).arg(p.stringStopBits).arg(p.stringFlowControl));
    } else {
        QMessageBox::critical(this, tr("Error"), serial->errorString());

        ui->statusBar->showMessage(tr("Open error"));
    }
}


void QOgreWidgetDemo::closeSerialPort()
{
    serial->close();
    console->setEnabled(false);
    ui->actionConnect->setEnabled(true);
    ui->actionDisconnect->setEnabled(false);
    ui->actionConfigure->setEnabled(true);
    ui->statusBar->showMessage(tr("Disconnected"));
}

void QOgreWidgetDemo::about()
{
    QMessageBox::about(this, tr("About Simple Terminal"),
                       tr("The <b>Simple Terminal</b> example demonstrates how to "
                          "use the Qt Serial Port module in modern GUI applications "
                          "using Qt, with a menu bar, toolbars, and a status bar."));
}

void QOgreWidgetDemo::writeData(const QByteArray &data)
{
    serial->write(data);
}


void QOgreWidgetDemo::readData()
{
        QByteArray data = serial->readAll();
        QString myValue(data);
        QStringList split =  myValue.split(" ");
        int k ;
		float x,y,z;
		float azi, pit, roll;
        for(int i = 0; i < split.size(); i++){
            console->putData(split[i].toLatin1());
            if(split[i].size() > 1){
                switch(k = split[i].at(0).toLatin1()){
                case 'a': // x acc
                    split[i].remove(0,1);
					//mOgreWidget->airplaneMove(0,0,split[i].toFloat());
					mOgreWidget->applyForceToAirplane(0,0,split[i].toFloat());
                    break;
                case 'b': // y acc
                    split[i].remove(0,1);
					//mOgreWidget->airplaneMove(0,split[i].toFloat(),0);
					mOgreWidget->applyForceToAirplane(0,split[i].toFloat(),0);
                    break;
                case 'c': // z acc
                    split[i].remove(0,1);
					mOgreWidget->airplaneMove(split[i].toFloat(),0,0);
					//mOgreWidget->applyForceToAirplane(split[i].toFloat(),0,0);
                    break;
                case 'd': //roll acc
                    split[i].remove(0,1);
					mOgreWidget->applyTorqueToAirplane(split[i].toFloat(),0,0);
					//mOgreWidget->airplaneMove(split[i].toFloat(),0,0);
                    break;
                case 'e':  //pitch acc
                    split[i].remove(0,1);
					mOgreWidget->applyTorqueToAirplane(0,split[i].toFloat(),0);
					//mOgreWidget->airplaneMove(0,split[i].toFloat(),0);
                    break;
                case 'f':   //yaw acc
                    split[i].remove(0,1);
					mOgreWidget->applyTorqueToAirplane(0,0,split[i].toFloat());
					//mOgreWidget->airplaneMove(0,0,split[i].toFloat());
                    break;
                case 'r': //reset message
                    split[i].remove(0,1);
                    break;
                case 'o': // change cotrol object
                    split[i].remove(0,1);
                    break;
                case 'n': 
                    split[i].remove(0,1);
					mOgreWidget->setFingerFactor(split[i].toInt());
                    break;
                case 'g' :
                    split[i].remove(0,1);
					azi = split[i].toFloat();
                    break;
                case 'h':  //pose_pitch
                    split[i].remove(0,1);
					pit = split[i].toFloat();
                    break;
                case 'i': //pose_roll
                    split[i].remove(0,1);
					roll = split[i].toFloat();
                    break;
                }
            }
            console->putData("\n");
        }
		
}

void QOgreWidgetDemo::handleError(QSerialPort::SerialPortError error)
{
    if (error == QSerialPort::ResourceError) {
        QMessageBox::critical(this, tr("Critical Error"), serial->errorString());
        closeSerialPort();
    }
}



void QOgreWidgetDemo::setBoundaryVisible(bool is){
}

void QOgreWidgetDemo::initActionsConnections()
{
    connect(ui->actionConnect, SIGNAL(triggered()), this, SLOT(openSerialPort()));
    connect(ui->actionDisconnect, SIGNAL(triggered()), this, SLOT(closeSerialPort()));
    connect(ui->actionQuit, SIGNAL(triggered()), this, SLOT(close()));
    connect(ui->actionConfigure, SIGNAL(triggered()), settings, SLOT(updateAndShow()));
    connect(ui->actionClear, SIGNAL(triggered()), console, SLOT(clear()));
    connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(about()));
    connect(ui->actionAboutQt, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
    connect(ui->actionShowBoundary, SIGNAL(triggered(bool)), this, SLOT(setBoundaryVisible(bool)));

}


void QOgreWidgetDemo::setController(bool is){
}


